const CHUNK_SIZE = 1 * 1024 * 1024;
const inputEl = document.getElementById('input')
let fileName = '';
// 上传文件
const handleUpload = async (e) => {
	const { files } = e.target;
	if (files.length === 0) return;
	fileName = files[0].name;
	// 拆分文件
	const chunkList = splitFile(files[0])

	// 计算hash
	const hash = await calculateHash(chunkList)
	console.log("文件的hash为：", hash)
	const { shouldUpload, uploadedChunkList } = await verfileIsExist(hash, getFileSuffix(fileName));
	console.log(shouldUpload)
	if (!shouldUpload) {
		alert("文件已存在，无需重复上传");
		return;
	}
	let uploadedChunkIndexList = [];
	if (uploadedChunkList?.length) {
		uploadedChunkIndexList = uploadedChunkList.map(item => {
			const arr = item.split("-");
			return parseInt(arr[arr.length - 1])
		})
		console.log(uploadedChunkIndexList)
		alert("已上传的区块号：" + uploadedChunkIndexList.toString())
	}
	const chunksData = chunkList.map((chunk, index) => ({
		chunk,
		hash: hash + "-" + index,
		progress: 0
	})).filter(item2 => {
		// 过滤掉已上传的块
		const arr = item2.hash.split("-")
		return uploadedChunkIndexList.indexOf(parseInt(arr[arr.length - 1])) === -1;
	})
	console.log(chunksData)
	// 开始上传分片
	uploadChunks(chunksData, hash)
	return false
}

inputEl.addEventListener('change', handleUpload)
// 获取文件后缀名
const getFileSuffix = (fileName) => {
	let arr = fileName.split(".");
	return arr.at(-1)
}
// 拆分文件
const splitFile = (file, size = CHUNK_SIZE) => {
	const fileChunkList = [];
	let curChunkIndex = 0;
	while (curChunkIndex <= file.size) {
		const chunk = file.slice(curChunkIndex, curChunkIndex + size);
		fileChunkList.push(chunk)
		curChunkIndex += size;
	}
	return fileChunkList;
}
// 上传分片
const uploadChunks = async (chunksData, hash) => {
	const formDataList = chunksData.map(({ chunk, hash }) => {
		const formData = new FormData()
		formData.append("chunk", chunk);
		formData.append("hash", hash);
		formData.append("suffix", getFileSuffix(fileName));
		return { formData };
	})

	const requestList = formDataList.map(({ formData }, index) => {
		return actionApi('/upload', formData, {
			// 不修改 Content-Type 属性，使用 FormData 默认的 Content-Type 值
			contentType: false,
			// 不对 FormData 中的数据进行 url 编码，而是将 FormData 数据原样发送到服务器
			processData: false
		})
	})
	// 上传文件
	Promise.all(requestList).then(() => {
		// 延迟发送合并请求，方便观察服务器合并文件的步骤
		setTimeout(() => {
			const params = {
				// 服务器存储的文件名：hash+文件后缀名
				fileHash: hash,
				suffix: getFileSuffix(fileName),
				// 用于服务器合并文件
				size: CHUNK_SIZE
			}
			mergeRequest(params);
		}, 1000);
	})
	return false
}
// 计算文件hash
const calculateHash = (chunkList) => {
	return new Promise(resolve => {
		const woker = new Worker('./utils/hash-worker.js')
		woker.postMessage({ chunkList })
		woker.onmessage = e => {
			const { percentage, hash } = e.data;
			if (hash) {
				// 当hash计算完成时，执行resolve
				resolve(hash)
			}
		}
	})
}
// 发送合并请求
const mergeRequest = (params) => {
	actionApi('/merge', JSON.stringify(params)).then(res => {
		console.log('合并完成')
	})
}
// 秒传：验证文件是否存在服务器
const verfileIsExist = async (fileHash, suffix) => {
	const params = {
		fileHash: fileHash,
		suffix: suffix
	}
	const res = await actionApi('/verFileIsExist', JSON.stringify(params), 'application/json')
	return res;
}
const actionApi = (url, params, config) => {
	return new Promise((resolve, reject) => {
		$.ajax({
			url: `http://localhost:3001${url}`,
			method: 'post',
			data: params,
			contentType: 'application/json',
			...config,
			// 成功回调
			success: res => {
				resolve(res)
				window.event.returnValue = false;
			},
			error: err => {
				reject(err)
			}
		})
	})
}
